<script lang="ts" setup>
import { computed, onBeforeUnmount, onMounted, ref } from 'vue';

const props = defineProps({
  title: {
    type: String,
    required: true,
  },
  icon: {
    type: Function,
    required: true,
  },
  type: {
    type: String,
    default: 'primary',
    validator: (value: string) =>
      ['danger', 'primary', 'success', 'warning'].includes(value),
  },
  content: {
    type: [String, Number, Object],
    default: '',
  },
  chart: {
    type: Boolean,
    default: false,
  },
});

const colorClasses = computed(() => {
  return {
    iconBg: `bg-${props.type}-100 dark:bg-${props.type}-900`,
    iconText: `text-${props.type}-600 dark:text-${props.type}-300`,
    hover: `hover:shadow-${props.type}-400 dark:hover:shadow-${props.type}-800`,
  };
});

// 3D 倾斜 + 缩放 + 眩光
const boardRef = ref<HTMLElement | null>(null);
const transform = ref('rotateX(0deg) rotateY(0deg) scale(1)');
const glare = ref({ x: '50%', y: '50%' });

// 控制光斑显示隐藏（实现渐隐效果）
const isHovering = ref(false);
let fadeTimeout: number | undefined;

let lastFrame = 0;

function handleMouseMove(e: MouseEvent) {
  const now = performance.now();
  if (now - lastFrame < 16) return; // 节流，每16ms执行一次
  lastFrame = now;
  if (!boardRef.value) return;
  const rect = boardRef.value.getBoundingClientRect();
  const x = e.clientX - rect.left;
  const y = e.clientY - rect.top;
  const centerX = rect.width / 2;
  const centerY = rect.height / 2;

  const rotateX = ((y - centerY) / centerY) * 10; // 最大倾斜 10deg
  const rotateY = ((x - centerX) / centerX) * -10;

  transform.value = `rotateX(${rotateX}deg) rotateY(${rotateY}deg) scale(1.03)`;

  glare.value = {
    x: `${(x / rect.width) * 100}%`,
    y: `${(y / rect.height) * 100}%`,
  };

  if (fadeTimeout) {
    clearTimeout(fadeTimeout);
    fadeTimeout = undefined;
  }
  isHovering.value = true;
}
function handleMouseLeave() {
  transform.value = 'rotateX(0deg) rotateY(0deg) scale(1)';
  isHovering.value = false;
  if (fadeTimeout) clearTimeout(fadeTimeout);
  fadeTimeout = window.setTimeout(() => {
    glare.value = { x: '50%', y: '50%' };
  }, 300);
}

onMounted(() => {
  boardRef.value?.addEventListener('mousemove', handleMouseMove);
  boardRef.value?.addEventListener('mouseleave', handleMouseLeave);
});

onBeforeUnmount(() => {
  boardRef.value?.removeEventListener('mousemove', handleMouseMove);
  boardRef.value?.removeEventListener('mouseleave', handleMouseLeave);
});
</script>

<template>
  <div
    ref="boardRef"
    class="relative flex w-full max-w-full flex-col rounded-xl transition-shadow duration-300 will-change-transform sm:max-w-md lg:max-w-xl"
    :class="colorClasses.hover"
    :style="{
      perspective: '1000px',
      boxShadow: isHovering
        ? `0 20px 40px rgba(0, 0, 0, 0.25), 0 10px 20px rgba(0, 0, 0, 0.15)`
        : `0 10px 20px rgba(0, 0, 0, 0.1)`,
      transform,
      transformStyle: 'preserve-3d',
      backfaceVisibility: 'hidden',
      minHeight: '250px',
    }"
  >
    <div
      class="pointer-events-none absolute inset-0 z-0 rounded-xl opacity-0 transition-opacity duration-300"
      :class="{ 'opacity-100': isHovering }"
      :style="{
        background: `radial-gradient(circle at ${glare.x} ${glare.y}, rgba(0,0,0,0.25), transparent 50%)`,
      }"
    ></div>

    <!-- 卡片主体 -->
    <div
      class="relative flex flex-1 flex-col rounded-xl bg-white p-3 shadow-md sm:p-4 dark:bg-gray-800"
      style="will-change: transform"
    >
      <div class="relative z-10 mb-3 flex items-start justify-between">
        <div class="rounded-lg p-2" :class="colorClasses.iconBg">
          <component
            :is="icon"
            class="text-2xl"
            :class="colorClasses.iconText"
          />
        </div>
      </div>

      <h3
        class="relative z-10 mb-3 text-base font-semibold text-gray-900 sm:text-lg dark:text-white"
      >
        {{ title }}
      </h3>

      <div class="relative z-10 flex-1 space-y-2 sm:space-y-3">
        <template v-if="!chart">
          <div
            v-if="typeof content === 'string' || typeof content === 'number'"
            class="text-xl font-bold text-gray-900 sm:text-2xl dark:text-white"
          >
            {{ content }}
          </div>
          <div v-else-if="typeof content === 'object'">
            <!-- 可自定义插槽替代展示对象 -->
          </div>
        </template>

        <template v-else>
          <slot name="chart"></slot>
        </template>
      </div>

      <div
        v-if="$slots.footer"
        class="relative z-10 border-t border-gray-200 pt-2 sm:pt-3 dark:border-gray-700"
      >
        <slot name="footer"></slot>
      </div>
    </div>
  </div>
</template>
